package newsrecommendation.datamodel.keywords;

import java.util.ArrayList;
import java.util.List;
import newsrecommendation.datamodel.utils.Scores;

/**
 *
 * @author Andrea
 */
public class UserKeywords {

    private List<Double> keywordScore_Historical;
    private List<Double> keywordScore_Survey;


    public UserKeywords() {
        keywordScore_Historical = new ArrayList();
        keywordScore_Survey = new ArrayList();
        for (int i = 0; i < Keywords.get().getSize(); i++) {
            keywordScore_Historical.add(0.0);
        }
        for (int i = 0; i < Keywords.get().getSize(); i++) {
            keywordScore_Survey.add(0.0);
        }
    }

    //EXPLICIT INTEREST --------------------------------------------------
    public void setInterests(List<Double> interests) { //Demographic
        resetInterest();
        if (!interests.isEmpty()) {
            keywordScore_Survey = interests;
        }
    }

    public void setInterestsPositions(String csv_Positions) {
        resetInterest();
        String[] positions = csv_Positions.split(",");
        for (int i = 0; i < positions.length; i++) {
            if (positions[i].contains("1")) {
                keywordScore_Survey.set(i, Scores.INTEREST);
            }
        }
    }

    public void setInterests(String csv_Keywords) { //Questionnaire
        resetInterest();
        String[] strKeywords = csv_Keywords.split(",");
        for (int i = 0; i < strKeywords.length; i++) {
            String keyword = strKeywords[i];
            int position = Keywords.get().getKeywordPosition(keyword);
            if (position != -1) {
                keywordScore_Survey.set(position, Scores.INTEREST);
            }
        }
    }

    public void setInterests(NewsKeywords keywords) { //Questionnaire
        resetInterest();
        for (int i = 0; i < keywords.getActivatedKeywords().size(); i++) {
            if (keywords.getActivatedKeywords().get(i) == 1.0) {
                keywordScore_Survey.set(i, Scores.INTEREST);
            }
        }
    }

    private void resetInterest() {
        //Reset Interests
        keywordScore_Survey.clear();
        for (int i = 0; i < Keywords.get().getSize(); i++) {
            keywordScore_Survey.add(0.0);
        }
    }

    //CLICK -------------------------------------------------------
    public void setClickNews(String csv_newsKeywords) {
        applyDecay(keywordScore_Historical);
        applyDecay(keywordScore_Survey);
        String[] strKeywords = csv_newsKeywords.split(",");
        for (int i = 0; i < strKeywords.length; i++) {
            String keyword = strKeywords[i];
            setClickOnKeyword(keyword);
        }
    }

    public void setClickNews(NewsKeywords keywords) {
        applyDecay(keywordScore_Historical);
        applyDecay(keywordScore_Survey);
        for (int i = 0; i < keywords.getActivatedKeywords().size(); i++) {
            if (keywords.getActivatedKeywords().get(i) == 1.0) {
                setClickOnKeyword(i);
            }
        }
    }

    private void setClickOnKeyword(String keyword) {
        int position = Keywords.get().getKeywordPosition(keyword);
        if (position != -1) {
            setClickOnKeyword(position);
        }
    }

    private void setClickOnKeyword(int position) {
        keywordScore_Historical.set(position, keywordScore_Historical.get(position) + Scores.CLICK);
    }
    //SET LIKE -------------------------------------------------------

    public void setLikeNews(String csv_newsKeywords) {
        String[] strKeywords = csv_newsKeywords.split(",");
        for (int i = 0; i < strKeywords.length; i++) {
            String keyword = strKeywords[i];
            setLikeOnKeyword(keyword);
        }
    }

    public void setLikeNews(NewsKeywords keywords) {
        for (int i = 0; i < keywords.getActivatedKeywords().size(); i++) {
            if (keywords.getActivatedKeywords().get(i) == 1.0) {
                setLikeOnKeyword(i);
            }
        }
    }

    private void setLikeOnKeyword(String keyword) {
        int position = Keywords.get().getKeywordPosition(keyword);
        if (position != -1) {
            setLikeOnKeyword(position);
        }
    }

    private void setLikeOnKeyword(int position) {
        keywordScore_Historical.set(position, keywordScore_Historical.get(position) +  Scores.LIKE);
    }

    //REMOVE LIKE -------------------------------------------------------
    public void removeLikeNews(String csv_newsKeywords) {
        String[] strKeywords = csv_newsKeywords.split(",");
        for (int i = 0; i < strKeywords.length; i++) {
            String keyword = strKeywords[i];
            removeLikeOnKeyword(keyword);
        }
    }

    public void removeLikeNews(NewsKeywords keywords) {
        for (int i = 0; i < keywords.getActivatedKeywords().size(); i++) {
            if (keywords.getActivatedKeywords().get(i) == 1.0) {
                removeLikeOnKeyword(i);
            }
        }
    }

    public void removeLikeOnKeyword(String keyword) {
        int position = Keywords.get().getKeywordPosition(keyword);
        if (position != -1) {
            removeLikeOnKeyword(position);
        }
    }

    private void removeLikeOnKeyword(int position) {
        if (keywordScore_Historical.get(position) >= Scores.LIKE) {
            keywordScore_Historical.set(position, keywordScore_Historical.get(position) - Scores.LIKE);
        } else {
            keywordScore_Historical.set(position, 0.0);
        }
    }

    //DECAY -------------------------------------------------------
    public void applyDecay(List<Double> keywordScore) {
        for (int i = 0; i < keywordScore.size(); i++) {
            if (keywordScore.get(i) == 0) {
                continue;
            }
            Double newValue = keywordScore.get(i) * Scores.DECAY;
            newValue = Math.round(newValue * 100.0) / 100.0; //Truncate... only use two decimals
            if (newValue < 0.95) {
                newValue = 0.0;
            }
            keywordScore.set(i, newValue);
        }
    }

    //INTEREST SCORE ------------------------------------------------------
    public double getInterestNewsScore(String csv_newsKeywords) {
        double scoreHistorical = getNewsScore(keywordScore_Historical, csv_newsKeywords);
        double scoreSurvey = getNewsScore(keywordScore_Survey, csv_newsKeywords);
        return (scoreHistorical + scoreSurvey) / 2;
    }

    public double getInterestNewsScore(NewsKeywords keywords) {
        double scoreHistorical = getNewsScore(keywordScore_Historical, keywords);
        double scoreSurvey = getNewsScore(keywordScore_Survey, keywords);
        return (scoreHistorical + scoreSurvey) / 2;
    }

    private double getNewsScore(List<Double> interests, String csv_newsKeywords) {
        int score = 0;
        String[] strKeywords = csv_newsKeywords.split(",");
        for (int i = 0; i < strKeywords.length; i++) {
            String keyword = strKeywords[i];

            int position = Keywords.get().getKeywordPosition(keyword);
            if (position != -1) {
                score += interests.get(position);
            }
        }
        if (getTotalPossible(interests) == 0) {
            return 0;
        }
        return (score / getTotalPossible(interests)) * 100;
    }

    private double getNewsScore(List<Double> interests, NewsKeywords keywords) {
        int score = 0;
        for (int i = 0; i < keywords.getActivatedKeywords().size(); i++) {
            if (keywords.getActivatedKeywords().get(i) == 1.0) {
                score += interests.get(i);
            }
        }
        if (getTotalPossible(interests) == 0) {
            return 0;
        }
        return (score / getTotalPossible(interests)) * 100;
    }

    private double getTotalPossible(List<Double> interests) {
        double totalScore = 0;
        for (Double score : interests) {
            totalScore += score;
        }
        return totalScore;
    }

    //TODO - BORRAR
    public String getKeywordsScore() {
        String all = "";
        for (int i = 0; i < keywordScore_Historical.size(); i++) {
            all = all + "," + Keywords.get().getAllKeywords().get(i) + "-" + (keywordScore_Historical.get(i)+keywordScore_Survey.get(i));
        }
        return all;
    }
}
